#pragma once
#include "stdafx.h"
#include "dgdef.h"
#include "aps.h"

using namespace std;
using namespace efsod;
using namespace aps;

namespace Staff2 {

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;
	using namespace System::IO;
	using namespace System::Text;
	using namespace System::Data::Odbc;

	/// <summary>
	/// Summary for Form1
	///
	/// WARNING: If you change the name of this class, you will need to change the
	///          'Resource File Name' property for the managed resource compiler tool
	///          associated with all .resx files this class depends on.  Otherwise,
	///          the designers will not be able to interact properly with localized
	///          resources associated with this form.
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{
	public:
		Form1(void)
		{
			InitializeComponent();
		}

	public: BYTE* d1;
	public: BYTE* d2;
	public: BYTE* d11;
	public: BYTE* d12;
	public: BYTE* d13;
	public: int len1;
	public: int len2;
	public: int len11;
	public: int len12;
	public: int len13;
	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}

	protected: 
	private: System::Windows::Forms::Button^  create;
	private: System::Windows::Forms::ToolTip^  toolTip1;
	private: System::Windows::Forms::Label^  csn;
	private: System::Windows::Forms::Button^  print;
	private: System::Windows::Forms::Label^  label1;
	private: System::Windows::Forms::RichTextBox^  progress;
	private: System::Windows::Forms::Button^  read;
	private: System::ComponentModel::IContainer^  components;

	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>


#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->components = (gcnew System::ComponentModel::Container());
			this->create = (gcnew System::Windows::Forms::Button());
			this->toolTip1 = (gcnew System::Windows::Forms::ToolTip(this->components));
			this->csn = (gcnew System::Windows::Forms::Label());
			this->print = (gcnew System::Windows::Forms::Button());
			this->label1 = (gcnew System::Windows::Forms::Label());
			this->progress = (gcnew System::Windows::Forms::RichTextBox());
			this->read = (gcnew System::Windows::Forms::Button());
			this->SuspendLayout();
			// 
			// create
			// 
			this->create->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->create->Location = System::Drawing::Point(341, 146);
			this->create->Name = L"create";
			this->create->Size = System::Drawing::Size(130, 26);
			this->create->TabIndex = 41;
			this->create->Text = L"Create files";
			this->create->UseVisualStyleBackColor = true;
			this->create->Click += gcnew System::EventHandler(this, &Form1::create_Click);
			// 
			// csn
			// 
			this->csn->AutoSize = true;
			this->csn->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->csn->Location = System::Drawing::Point(279, 32);
			this->csn->Name = L"csn";
			this->csn->Size = System::Drawing::Size(70, 13);
			this->csn->TabIndex = 38;
			this->csn->Text = L"Not Available";
			// 
			// print
			// 
			this->print->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->print->Location = System::Drawing::Point(341, 209);
			this->print->Name = L"print";
			this->print->Size = System::Drawing::Size(130, 25);
			this->print->TabIndex = 37;
			this->print->Text = L"Print e-Passport";
			this->print->UseVisualStyleBackColor = true;
			this->print->Click += gcnew System::EventHandler(this, &Form1::print_Click);
			// 
			// label1
			// 
			this->label1->AutoSize = true;
			this->label1->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->label1->Location = System::Drawing::Point(19, 68);
			this->label1->Name = L"label1";
			this->label1->Size = System::Drawing::Size(56, 13);
			this->label1->TabIndex = 36;
			this->label1->Text = L"Progress";
			// 
			// progress
			// 
			this->progress->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->progress->Location = System::Drawing::Point(22, 84);
			this->progress->Name = L"progress";
			this->progress->Size = System::Drawing::Size(281, 150);
			this->progress->TabIndex = 35;
			this->progress->Text = L"";
			// 
			// read
			// 
			this->read->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->read->Location = System::Drawing::Point(22, 22);
			this->read->Name = L"read";
			this->read->Size = System::Drawing::Size(218, 23);
			this->read->TabIndex = 34;
			this->read->Text = L"Read Passport Chip Serial Number";
			this->read->UseVisualStyleBackColor = true;
			this->read->Click += gcnew System::EventHandler(this, &Form1::read_Click);
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->AutoScroll = true;
			this->ClientSize = System::Drawing::Size(528, 296);
			this->Controls->Add(this->create);
			this->Controls->Add(this->csn);
			this->Controls->Add(this->print);
			this->Controls->Add(this->label1);
			this->Controls->Add(this->progress);
			this->Controls->Add(this->read);
			this->Name = L"Form1";
			this->Text = L"E-Passport Writing Interface";
			this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
	private: System::Void create_Click(System::Object^  sender, System::EventArgs^  e) {
				//TODO
				//Creates EFSOD
				bool ok = false;
				if(ok) this->print->Enabled = true;
				else this->print->Enabled = false;
		 }

	private: System::Void print_Click(System::Object^  sender, System::EventArgs^  e) {
				 //TODO
				 //prints to passport
				 //it wont be activated till create is also clicked
				this->progress->AppendText("Printing started \r");
				this->progress->AppendText("Printing finished \r");
		 }

	private: System::Void read_Click(System::Object^  sender, System::EventArgs^  e) {
				 //TODO
				 //3. Check if CSN number exists in database or not, and DGs generated are same as on card
				 
				 bool verified = false;
				 System::String ^str = "dsn=Passport Data;uid=siddhu;pwd=siddhu;";
				 System::Data::Odbc::OdbcConnection ^connection = gcnew System::Data::Odbc::OdbcConnection(str);
				 System::Data::Odbc::OdbcCommand ^command = connection->CreateCommand();
				 System::Data::Odbc::OdbcDataReader ^Reader;
				 
				 //read csn from smart card
				 int csno = 101;
				 command->CommandText = "SELECT * FROM pdata WHERE chip_serial_no ='" + csno +"'";
				 this->csn->Text = csno.ToString();
				 connection->Open();
				 Reader = command->ExecuteReader();
				 if(!Reader->Read()) {
					 this->progress->AppendText("CSN does not exist in database\r");;
					return ;
				 }

				System::String ^s = Reader->GetValue(Reader->GetOrdinal("file_number"))->ToString();
				System::String ^p = Reader->GetValue(Reader->GetOrdinal("passport_no"))->ToString();
				int len = s->Length;
				array<wchar_t, 1> ^c = gcnew array<wchar_t, 1>(len);
				c = s->ToCharArray();
				char* fileno = (char*)malloc(20);
				for(int i=0;i<len;i++) fileno[i] = c[i];
				fileno[len] = '\0';

				int fileSize = 65*1024;
				array<System::Byte, 1> ^rawData = gcnew array<System::Byte, 1>(fileSize);
				System::IO::FileStream ^fs = gcnew System::IO::FileStream("FaceImage.jpg", System::IO::FileMode::OpenOrCreate, System::IO::FileAccess::Write);
				Reader->GetBytes(Reader->GetOrdinal("portrait_image"), 0, rawData, 0, fileSize);
				fs->Write(rawData, 0, fileSize);
				fs->Close();
				connection->Close();
				
				BYTE d1[100];
				BYTE d2[20000];
				BYTE d11[500];
				BYTE d12[200];
				BYTE d13[500];
				BYTE COM[100];

				this->progress->AppendText("Processing started for passport number " + p + "\r");
				try {
				len1 = aps::createDG1(fileno, d1, 100);
				this->progress->AppendText("DG1 created\r" );
				ofstream fout1("DG1.bin", ios::binary);
				fout1.write((char*)d1, len1);

				len2 = aps::createDG2(fileno, d2, 20000);
				this->progress->AppendText("DG2 created\r");
				ofstream fout2("DG2.bin", ios::binary);
				fout2.write((char*)d2, len2);
				
				len12 = aps::createDG12(fileno, "doc_signer.der", d12, 200);
				this->progress->AppendText("DG12 created\r");
				ofstream fout12("DG12.bin", ios::binary);
				fout12.write((char*)d12, len12);
				
				len13 = aps::createDG13(fileno, d13, 500);
				this->progress->AppendText("DG13 created\r");
				ofstream fout13("DG13.bin", ios::binary);
				fout13.write((char*)d13, len13);
				
				len11 = aps::createDG11(fileno, d11, 500);
				this->progress->AppendText("DG11 created\r");
				ofstream fout11("DG11.bin", ios::binary);
				fout11.write((char*)d11, len11);
				
				int clen = efsod::createEFCOM(COM, 100);
				this->progress->AppendText("EFCOM created\r");
				ofstream cfout("EF_COM.bin", ios::binary);
				cfout.write((char*)COM, clen);
				
				//Read data from card and veridy DG1, DG2, DG11, DG13
				//if verified then set verify = true, 
				verified = true;
				if(verified) {
					BYTE ldsSO[1000];
					BYTE dataToSign[100];
					BYTE sod[5000];
					int ldsSOLength = sizeof(ldsSO);
					int dataToSignLen = sizeof(dataToSign);
					int sodLength = sizeof(sod);
					DG dgs[5] = {{1, len1, d1}, {2, len2, d2}, {11, len11, d11}, {12, len12, d12}, {13, len13, d13}};

					int j = efsod::createLDSSecurityObject(dgs, 5, "sha-1", ldsSO, &ldsSOLength, "sha-1", dataToSign, &dataToSignLen);
					if (j != EFSOD_SUCCESS) this->progress->AppendText("Error in creating LDS\r");
					else this->progress->AppendText("EFSOD created\r");
					ofstream ldsf("LDS.bin", ios::binary);
					ldsf.write((char*)ldsSO, ldsSOLength);

					ofstream data("dataToSign.bin", ios::binary);
					data.write((char*)dataToSign, dataToSignLen);
					this->progress->AppendText("Processing done for passport number " + p + "\r");
				}
				else this->progress->AppendText("Verification failed\r");
				}
				catch (System::Exception ^excp) {
					this->progress->AppendText("Kindly execute again\r");
				}
		 }

private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
			 this->create->Enabled = false;
			 this->print->Enabled = false;
		 }
};
}